/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "timeline_service.h"

#include <ipc_skeleton.h>
#include "if_system_ability_manager.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"

#include "timeline_permission.h"
#include "timeline_common.h"

namespace OHOS {
namespace Msdp {
namespace {
auto ms = DelayedSpSingleton<TimelineService>::GetInstance();
const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(ms.GetRefPtr());
}
TimelineService::TimelineService() : SystemAbility(MSDP_TIMELINE_SERVICE_ID, true)
{
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "Add SystemAbility");
}

TimelineService::~TimelineService() {}

void TimelineService::OnStart()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Enter");
    if (ready_) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "OnStart is ready, nothing to do.");
        return;
    }

    if (!Init()) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "OnStart call init fail");
        return;
    }
    if (!Publish(DelayedSpSingleton<TimelineService>::GetInstance())) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "OnStart register to system ability manager failed");
        return;
    }
    ready_ = true;
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "OnStart and add system ability success");
}

void TimelineService::OnStop()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Enter");
    if (!ready_) {
        return;
    }
    ready_ = false;
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Exit");
}

bool TimelineService::Init()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "TimelineService::Enter");

    if (!timelineManager_) {
        timelineManager_ = std::make_shared<TimelineManager>(ms);
    }
    if (!timelineManager_->Init()) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineManager OnStart init fail");
        return false;
    }
    if (!timelinerdbmgr_) {
        timelinerdbmgr_ = std::make_shared<TimelineRdbManager>();
    }
    if (!timelinerdbmgr_->Init()) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineRdbManager OnStart init fail");
        return false;
    }
    return true;
}

bool TimelineService::IsServiceReady()
{
    return ready_;
}

std::shared_ptr<TimelineManager> TimelineService::GetTimelineManager()
{
    return timelineManager_;
}

void TimelineService::Subscribe(const TimelineDataUtils::TimelineArea& area,
    const sptr<ITimelineCallback>& callback)
{
    timelineManager_->Subscribe(area, callback);
}

void TimelineService::UnSubscribe(const TimelineDataUtils::TimelineArea& area,
    const sptr<ITimelineCallback>& callback)
{
    timelineManager_->UnSubscribe(area, callback);
}

bool TimelineService::SetPositionState(int32_t homevalue, int32_t companyvalue)
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetPositionState : fun is start");
    if (homevalue > 1 || companyvalue > 1 || homevalue == companyvalue) {
        return -1;
    }
    return timelineManager_->UpdatePositionState(homevalue, companyvalue);
}

bool TimelineService::SetHomePosition(double longitude, double latitude)
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetHomePosition : fun is start");
    if (longitude > 180 || longitude < -180 || latitude > 90 || latitude < -90){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetHomePosition : Not Correct Position");
        return -1;
    }
    return timelineManager_->UpdateHomePosition(longitude, latitude);
}

bool TimelineService::SetCompanyPosition(double longitude, double latitude)
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetCompanyPosition : fun is start");
    if (longitude > 180 || longitude < -180 || latitude > 90 || latitude < -90){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetCompanyPosition : Not Correct Position");
        return -1;
    }
    return timelineManager_->UpdateCompanyPosition(longitude, latitude);
}

bool TimelineService::SetSleepTime(int32_t sleeptime, int32_t wakeuptime)
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetSleepTime : fun is start");
    if (sleeptime > 23 || wakeuptime >23){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetSleepTime : Not Correct Time");
        return -1;
    }
    if (sleeptime == wakeuptime){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetSleepTime : Not Correct Duration");
        return -1;
    }
    return timelinerdbmgr_->UpdateSleepTime(sleeptime, wakeuptime);
}

bool TimelineService::SetRestTime(int32_t resttimestart, int32_t resttimeend)
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetRestTime : fun is start");
    if (resttimestart > 23 || resttimeend >23){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetRestTime : Not Correct Time");
        return -1;
    }
    if (resttimestart == resttimeend){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetSleepTime : Not Correct Duration");
        return -1;
    }
    return timelineManager_->UpdateRestTime(resttimestart, resttimeend);
}

bool TimelineService::SetWorkTime(int32_t worktimestart, int32_t worktimeend)
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::UpdateRestTime : fun is start");
    if (worktimestart > 23 || worktimeend >23){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::UpdateRestTime : Not Correct Time");
        return -1;
    }
    if (worktimestart == worktimeend){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::SetSleepTime : Not Correct Duration");
        return -1;
    }
    return timelineManager_->UpdateWorkTime(worktimestart, worktimeend);
}

uint32_t TimelineService::GetSleepTime()
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::GetSleepTime : fun is start");
    return timelinerdbmgr_->GetSleepTime();
}

uint32_t TimelineService::GetWakeupTime()
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::GetWakeupTime : fun is start");
    return timelinerdbmgr_->GetWakeupTime();
}

uint32_t TimelineService::GetRestTimeStart()
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::GetRestTimeStart : fun is start");
    return timelineManager_->GetRestTimeStart();
}

uint32_t TimelineService::GetRestTimeEnd()
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::GetRestTimeEnd : fun is start");
    return timelineManager_->GetRestTimeEnd();
}

uint32_t TimelineService::GetWorkTimeStart()
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::GetWorkTimeStart : fun is start");
    return timelineManager_->GetWorkTimeStart();
}

uint32_t TimelineService::GetWorkTimeEnd()
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::GetWorkTimeEnd : fun is start");
    return timelineManager_->GetWorkTimeEnd();
}

TimelineDatabaseInfo::ForcecastPosition TimelineService::GetForcecast(uint32_t time)
{
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::GetForcecast : fun is start");
    if (time > 23 || time < 0){
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TimelineService::GetForcecast : Not Correct Time");
        return TimelineDatabaseInfo::ForcecastPosition::UNKNOWN;
    }
    timelineManager_->CheckRate(time);
    return timelineManager_->GetForcecastPosition();
}
} // namespace Msdp
} // namespace OHOS
